/* Copyright (c) 2009-2010, Sean A.O. Harney <sharney3@gmail.com> */

#include "omf.h"


// creates a zipfile of all entries in dirname, does not go into subdirs.
// return NULL on error, or else zip filename.
char *create_zip_of_dir(char *dirname)
{
    int i;
    static char zip_name_stem[500];	//TODO: change this so it is passed in 
    static char zip_name[512];	//TODO: change this so it is passed in 
    struct zip *zipp = NULL;
    struct zip_source *source = NULL;
    int zip_error;
    DIR *dp;
    struct dirent *dents;
    char *file_name;
    char file_path[1024];
    char file_zip_path[1024];

    dp = opendir(dirname);
    if (dp == NULL)
      {
	  perror(dirname);
	  return NULL;
      }



/* NOTE:
 * OMFoutputlog.31570.__p_omf.il5kMd/PA/3165._usr_bin_openssl.xM6zev
 * =>
 * OMFoutputlog.31570.__p_omf.il5kMd_PA_3165._usr_bin_openssl.xM6zev.zip
 */
    for (i = 0; i < strlen(dirname) && i < sizeof(zip_name_stem) - 1; i++)
	zip_name_stem[i] = (dirname[i] == '/') ? '_' : dirname[i];
    zip_name_stem[i] = '\0';


    snprintf(zip_name, sizeof(zip_name), "%s.zip", zip_name_stem);
    debug1_printf("zip_name: %s\n", zip_name);


    zipp = zip_open(zip_name, ZIP_CREATE | ZIP_EXCL, &zip_error);
    if (zipp == NULL)
      {
	  char tmp[128];
	  zip_error_to_str(tmp, sizeof(tmp), zip_error, errno);
	  fprintf(stderr, "zip_open() failed: %s\n", tmp);
	  goto close_down;
      }

    if (zip_add_dir(zipp, zip_name_stem) == -1)
      {

	  fprintf(stderr, "error adding dir: %s: %s\n", zip_name_stem,
		  zip_strerror(zipp));
	  goto close_down;
      }

    while (1)
      {
	  errno = 0;
	  dents = readdir(dp);
	  if (dents == NULL)
	    {
		if (errno != 0)
		  {
		      perror("readdir()");
		      goto close_down;
		  }
		/* else no more entries */
		break;
	    }

	  file_name = dents->d_name;
	  if (!strcmp(file_name, ".") || !strcmp(file_name, ".."))	/* skip over . and .. */
	      continue;

	  snprintf(file_path, sizeof(file_path), "%s/%s", dirname,
		   file_name);
	  snprintf(file_zip_path, sizeof(file_zip_path), "%s/%s",
		   zip_name_stem, file_name);


	  if ((source = zip_source_file(zipp, file_path, 0, 0)) == NULL)
	    {
		fprintf(stderr, "zip_source_buffer(): %s: %s\n",
			file_zip_path, zip_strerror(zipp));
		goto close_down;

	    }

	  if (zip_add(zipp, file_zip_path, source) == -1)
	    {
		zip_source_free(source);
		fprintf(stderr, "error adding file: %s: %s\n", file_path,
			zip_strerror(zipp));
		goto close_down;
	    }
	  //NOTE: cant zip_source_free, will zip_close take care of this?
	  //zip_source_free(source);
	  debug1_printf("Added %s to zip file as %s .\n", file_path,
			file_zip_path);
      }				/* end while */

    closedir(dp);
    zip_close(zipp);

    debug1_printf("Successfully created zip file:  %s\n", zip_name);

    return zip_name;

  close_down:
    closedir(dp);
    /* closing zipp seems to segfault so dont bother */
    return NULL;
}
